package com.packer.ext.http;

import android.os.Environment;
import android.text.TextUtils;

import com.packer.ext.interceptor.AddCookiesInterceptor;
import com.packer.ext.interceptor.CacheInterceptor;
import com.packer.ext.interceptor.HeaderInterceptor;
import com.packer.ext.interceptor.ReceivedCookiesInterceptor;

import java.io.File;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
import okhttp3.Cache;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * 获取retrofit实例
 * 网络相关设置
 */
public class RetrofitManager {
    private OkHttpClient.Builder mOkHttpClientBuilder;
    private Retrofit mRetrofit;

    private static class NetWorkManagerHolder {
        private static final RetrofitManager INSTANCE = new RetrofitManager();
    }

    public static final RetrofitManager getInstance() {
        return NetWorkManagerHolder.INSTANCE;
    }


    public void init(String appDefaultDomain) {
        this.mRetrofit = new Retrofit.Builder()
                .baseUrl(appDefaultDomain)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .client(mOkHttpClientBuilder.build())
                .build();
    }

    private RetrofitManager() {
        mOkHttpClientBuilder = RetrofitUrlManager.getInstance().with(new OkHttpClient.Builder())
                .readTimeout(5, TimeUnit.SECONDS)
                .connectTimeout(5, TimeUnit.SECONDS);
    }


    /**
     * 添加统一的请求头
     *
     * @param headerMaps
     * @return
     */
    public RetrofitManager setHeaders(Map<String, Object> headerMaps) {
        mOkHttpClientBuilder.addInterceptor(new HeaderInterceptor(headerMaps));
        return this;
    }

    /**
     * 信任所有证书,不安全有风险
     *
     * @return
     */
    public RetrofitManager setSslSocketFactory() {
        SSLUtils.SSLParams sslParams = SSLUtils.getSslSocketFactory();
        mOkHttpClientBuilder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
        return this;
    }

    /**
     * 使用预埋证书，校验服务端证书（自签名证书）
     *
     * @param certificates
     * @return
     */
    public RetrofitManager setSslSocketFactory(InputStream... certificates) {
        SSLUtils.SSLParams sslParams = SSLUtils.getSslSocketFactory(certificates);
        mOkHttpClientBuilder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
        return this;
    }

    /**
     * 持久化保存cookie保存到sp文件中
     *
     * @param saveCookie
     * @return
     */
    public RetrofitManager setCookie(boolean saveCookie) {
        if (saveCookie) {
            mOkHttpClientBuilder
                    .addInterceptor(new AddCookiesInterceptor())
                    .addInterceptor(new ReceivedCookiesInterceptor());
        }
        return this;
    }

    /**
     * 开启缓存，缓存到默认路径
     *
     * @return
     */
    public RetrofitManager setCache() {
        Cache cache = new Cache(new File(Environment.getExternalStorageDirectory().getPath() + "/rxHttpCacheData")
                , 1024 * 1024 * 100);
        CacheInterceptor cacheInterceptor = new CacheInterceptor();
        mOkHttpClientBuilder.addInterceptor(cacheInterceptor)
                .addNetworkInterceptor(cacheInterceptor)
                .cache(cache);
        return this;
    }

    /**
     * 设置缓存路径及缓存文件大小
     *
     * @param cachePath
     * @param maxSize
     * @return
     */
    public RetrofitManager setCache(String cachePath, long maxSize) {
        if (!TextUtils.isEmpty(cachePath) && maxSize > 0) {
            CacheInterceptor cacheInterceptor = new CacheInterceptor();
            Cache cache = new Cache(new File(cachePath), maxSize);
            mOkHttpClientBuilder
                    .addInterceptor(cacheInterceptor)
                    .addNetworkInterceptor(cacheInterceptor)
                    .cache(cache);
        }

        return this;
    }

    public Retrofit getRetrofit() {
        return mRetrofit;
    }
}